﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using Salamanca;
using Salamanca.DataActivities;
using Salamanca.DataActivities.UI;
using Salamanca.DataRules;
#if (!NET_CF)
using System.Diagnostics.CodeAnalysis;
#endif

namespace Debugging.Activities
{

    /// <summary>Initial state of the Sample activity.</summary>
    public sealed partial class SampleActivity:
        SampleActivity<Sample.Data>
    {
        /// <summary>Possible outcomes from the <see cref="SampleActivity{TActivityData}">activity state</see>.</summary>
        internal enum Transition
        {
            Transition2,
            Transition1
        }

        /// <summary>Creates an new instance of the <see cref="SampleActivity" /> class.</summary>
        public SampleActivity(Sample.Parameters parameters):
            base(new Sample.Data(), parameters)
        {
        }

    }

    /// <summary>Initial state of the Sample subactivity.</summary>
    public partial class SampleActivity<TActivityData>:
        ActivityState<TActivityData>,
        IActivityInitialState
        where TActivityData:
            Sample.IData
    {

        /// <summary>Creates an new instance of the <see cref="SampleActivity{TActivityData}" /> class.</summary>
        public SampleActivity(TActivityData data, Sample.IParameters parameters):
            base(data, parameters)
        {
        }

        /// <summary>Gets to the next state.</summary>
        protected override ActivityStateResult Handle(IActivityController controller)
        {
            return ActivityStateResult.Next;
        }

        /// <summary>Gets the next state.</summary>
        protected override IActivityState NextState
        {
            get
            {
                return Sample.NextStateProvider<TActivityData>.GetStartState(Data, (Sample.IParameters)Parameters);
            }
        }

    }
}

namespace Debugging.Activities.Sample
{

    /// <summary />
    public partial interface IDataReader
    {

        /// <summary />
        IList<System.String> DataAttribute1 { get; }

        /// <summary />
        string DataAttribute2 { get; }
    }

    public partial interface IData:
        IActivityData,
        IDataReader
    {

        /// <summary />
        new IList<System.String> DataAttribute1 { get; set; }

        /// <summary />
        new string DataAttribute2 { get; set; }
    }

    /// <summary>Question factory interface for the Sample activity.</summary>
    public partial interface IQuestionFactory
    {

        /// <summary>Creates the <see cref="Question" /> for the <see cref="QuestionState1" /> question state.</summary>
        Question GetQuestionState1Question(ActivityController controller, IDataReader data, IDataBag<IList<System.String>> answer);

        /// <summary>Creates the <see cref="Question" /> for the <see cref="QuestionState2" /> question state.</summary>
        Question GetQuestionState2Question(ActivityController controller, IDataReader data, string answer);
    }

    public partial class Data:
        ActivityData,
        IData
    {
        private partial struct Backup
        {
        }

        /// <summary />
        public IList<System.String> DataAttribute1
        {
            get
            {
                return new ReadOnlyCollection<System.String>(_DataAttribute1);
            }
            set
            {
                _DataAttribute1=new List<System.String>(value);
            }
        }

        /// <summary />
        public string DataAttribute2
        {
            get
            {
                return _DataAttribute2;
            }
            set
            {
                _DataAttribute2=value;
            }
        }

        /// <summary />
        private List<System.String> _DataAttribute1=new List<System.String>();

        /// <summary />
        private string _DataAttribute2;
    }

    public partial interface IParameters:
        IQuestionFactoryParameters<IQuestionFactory>
    {
    }


    public partial class Parameters:
        IParameters
    {
        public Parameters(IQuestionFactory factory)
        {
            Debug.Assert(factory!=null);
            if (factory==null)
                throw new ArgumentNullException("factory");

            _QuestionFactory=factory;
        }

        public IQuestionFactory QuestionFactory
        {
            get
            {
                return _QuestionFactory;
            }
        }

        private IQuestionFactory _QuestionFactory;
    }

    /// <summary>Activity states provider for the Sample activity.</summary>
    internal static class NextStateProvider<TActivityData>
        where TActivityData:
            IData
{

        /// <summary>Returns the first activity state for the Sample activity.</summary>
        internal static ActivityState<TActivityData> GetStartState(TActivityData data, IParameters parameters)
        {
            // Add a custom method to your code with the following signature:
            // private static SampleActivity.Transition GetStartTransition(IDataReader data, IParameters parameters)
            // {
            // }
            SampleActivity.Transition transition=GetStartTransition(data, parameters);

            switch (transition)
            {
            case SampleActivity.Transition.Transition2:
                return new QuestionState2<TActivityData, IQuestionFactory>(
                    data,
                    parameters,
                    delegate(TActivityData d, IActivityParameters p) {
                        return _GetQuestionState2NextState(d, (IParameters)p);
                    }
                );
            case SampleActivity.Transition.Transition1:
                return new QuestionState1<TActivityData, IQuestionFactory>(
                    data,
                    parameters,
                    delegate(TActivityData d, IActivityParameters p) {
                        return _GetQuestionState1NextState(d, (IParameters)p);
                    }
                );
            }

            throw new InvalidOperationException("Invalid transition.");
        }

        /// <summary>Returns the activity state following QuestionState1 in the Sample activity.</summary>
        private static ActivityState<TActivityData> _GetQuestionState1NextState(TActivityData data, IParameters parameters)
        {
            // Add a custom method to your code with the following signature:
            // private static QuestionState1.Transition GetQuestionState1Transition(IDataReader data, IParameters parameters)
            // {
            // }
            QuestionState1.Transition transition=GetQuestionState1Transition(data, parameters);

            switch (transition)
            {
            case QuestionState1.Transition.Transition2:
                return new ActionState2<TActivityData>(
                    data,
                    parameters,
                    delegate(TActivityData d, IActivityParameters p) {
                        return _GetActionState2NextState(d, (IParameters)p);
                    }
                );
            case QuestionState1.Transition.Transition1:
                return new ActionState1<TActivityData>(
                    data,
                    parameters,
                    delegate(TActivityData d, IActivityParameters p) {
                        return _GetActionState1NextState(d, (IParameters)p);
                    }
                );
            }

            throw new InvalidOperationException("Invalid transition.");
        }

        /// <summary>Returns the activity state following QuestionState2 in the Sample activity.</summary>
        private static ActivityState<TActivityData> _GetQuestionState2NextState(TActivityData data, IParameters parameters)
        {
                return new ActionState2<TActivityData>(
                    data,
                    parameters,
                    delegate(TActivityData d, IActivityParameters p) {
                        return _GetActionState2NextState(d, (IParameters)p);
                    }
                );
        }

        /// <summary>Returns the activity state following ActionState1 in the Sample activity.</summary>
        private static ActivityState<TActivityData> _GetActionState1NextState(TActivityData data, IParameters parameters)
        {
                return new EndActivityState<TActivityData>(data);
        }

        /// <summary>Returns the activity state following ActionState2 in the Sample activity.</summary>
        private static ActivityState<TActivityData> _GetActionState2NextState(TActivityData data, IParameters parameters)
        {
                return new EndActivityState<TActivityData>(data);
        }
    }

    /// <summary></summary>
    internal static partial class QuestionState1
    {
        /// <summary>Possible outcomes from the <see cref="QuestionState1{TActivityData}">activity state</see>.</summary>
        internal enum Transition
        {
            Transition2,
            Transition1
        }
    }

    /// <summary>Inner state of the Sample activity.</summary>
    internal partial class QuestionState1<TActivityData, TQuestionFactory>:
        QuestionActivityState<TActivityData>
        where TQuestionFactory:
            IQuestionFactory
        where TActivityData:
            IData
    {

        /// <summary>Allows this question to be answered.</summary>
        private class LocalAnswer:
            IDataBag<IList<System.String>>
        {

            /// <summary>Creates a new instance of the <see cref="LocalAnswer" /> class.</summary>
            internal LocalAnswer(TActivityData data)
            {
                _Data=data;
            }

            public IList<System.String> Data
            {
                get
                {
                    return _Data.DataAttribute1;
                }
                set
                {
                    _Data.DataAttribute1=value;
                }
            }

            private TActivityData _Data;
        }

        /// <summary>Creates a new instance of the <see cref="QuestionState1{TActivityData,TQuestionFactory}" /> class.</summary>
        public QuestionState1(TActivityData data, IQuestionFactoryParameters<TQuestionFactory> parameters, NextStateCreateHandler<TActivityData> nextStateCreator):
            base(data, parameters)
        {
            _NextStateCreator=nextStateCreator;
        }

        /// <summary>Raises the <see cref="ActivityState{TActivityData}.Initialized" /> event.</summary>
        protected override void OnInitialized(ActivityStateEventArgs e)
        {
            Question=((IQuestionFactoryParameters<TQuestionFactory>)Parameters)
                .QuestionFactory
                .GetQuestionState1Question((ActivityController)e.Controller, Data, new LocalAnswer(Data));

            base.OnInitialized(e);
        }

        /// <summary>Gets the next state.</summary>
        protected override IActivityState NextState
        {
            get
            {
                if (_NextStateCreator!=null)
                    return _NextStateCreator(Data, Parameters);

                return new EndActivityState<TActivityData>(Data);
            }
        }

        private NextStateCreateHandler<TActivityData> _NextStateCreator;
    }

    /// <summary>Inner state of the Sample activity.</summary>
    internal partial class QuestionState2<TActivityData, TQuestionFactory>:
        QuestionActivityState<TActivityData>
        where TQuestionFactory:
            IQuestionFactory
        where TActivityData:
            IData
    {

        /// <summary>Creates a new instance of the <see cref="QuestionState2{TActivityData,TQuestionFactory}" /> class.</summary>
        public QuestionState2(TActivityData data, IQuestionFactoryParameters<TQuestionFactory> parameters, NextStateCreateHandler<TActivityData> nextStateCreator):
            base(data, parameters)
        {
            _NextStateCreator=nextStateCreator;
        }

        /// <summary>Raises the <see cref="ActivityState{TActivityData}.Initialized" /> event.</summary>
        protected override void OnInitialized(ActivityStateEventArgs e)
        {
            Question=((IQuestionFactoryParameters<TQuestionFactory>)Parameters)
                .QuestionFactory
                .GetQuestionState2Question((ActivityController)e.Controller, Data, Data.DataAttribute2);

            base.OnInitialized(e);
        }

        /// <summary>Gets the next state.</summary>
        protected override IActivityState NextState
        {
            get
            {
                if (_NextStateCreator!=null)
                    return _NextStateCreator(Data, Parameters);

                return new EndActivityState<TActivityData>(Data);
            }
        }

        private NextStateCreateHandler<TActivityData> _NextStateCreator;
    }

    /// <summary>Inner state of the Sample activity.</summary>
    internal partial class ActionState1<TActivityData>:
        ActivityState<TActivityData>
        where TActivityData:
            IData
    {

        /// <summary>Creates a new instance of the <see cref="ActionState1{TActivityData}" /> class.</summary>
        public ActionState1(TActivityData data, IParameters parameters, NextStateCreateHandler<TActivityData> nextStateCreator):
            base(data, parameters)
        {
            _NextStateCreator=nextStateCreator;
        }

        /// <summary>Gets the next state.</summary>
        protected override IActivityState NextState
        {
            get
            {
                if (_NextStateCreator!=null)
                    return _NextStateCreator(Data, Parameters);

                return new EndActivityState<TActivityData>(Data);
            }
        }

        private NextStateCreateHandler<TActivityData> _NextStateCreator;
    }

    /// <summary>Inner state of the Sample activity.</summary>
    internal partial class ActionState2<TActivityData>:
        ActivityState<TActivityData>
        where TActivityData:
            IData
    {

        /// <summary>Creates a new instance of the <see cref="ActionState2{TActivityData}" /> class.</summary>
        public ActionState2(TActivityData data, IParameters parameters, NextStateCreateHandler<TActivityData> nextStateCreator):
            base(data, parameters)
        {
            _NextStateCreator=nextStateCreator;
        }

        /// <summary>Gets the next state.</summary>
        protected override IActivityState NextState
        {
            get
            {
                if (_NextStateCreator!=null)
                    return _NextStateCreator(Data, Parameters);

                return new EndActivityState<TActivityData>(Data);
            }
        }

        private NextStateCreateHandler<TActivityData> _NextStateCreator;
    }
}

